package com.wuliu.system.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wuliu.common.constant.QueueConstants;
import com.wuliu.common.core.domain.Message;
import com.wuliu.common.core.domain.SendSmsInfoDto;
import com.wuliu.common.core.redis.RedisCache;
import com.wuliu.common.utils.DateUtils;

import com.wuliu.common.utils.DictUtils;
import com.wuliu.common.utils.StringUtils;
import com.wuliu.common.utils.YDMsgUtils;
import com.wuliu.system.domain.SysAccount;
import com.wuliu.system.mapper.SysAccountMapper;
import com.wuliu.system.service.rabbitmq.RabbitMQService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import com.wuliu.system.mapper.SysSmsRecordMapper;
import com.wuliu.system.domain.SysSmsRecord;
import com.wuliu.system.service.ISysSmsRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

/**
 * 短信发送记录Service业务层处理
 *
 * @author realue
 * @date 2023-11-02
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysSmsRecordServiceImpl extends ServiceImpl<SysSmsRecordMapper, SysSmsRecord> implements ISysSmsRecordService {
    private static final int MSG_NUB = 70;         //短信字数规格，每70个字符算一条短信

    private final SysSmsRecordMapper sysSmsRecordMapper;

    private final SysAccountMapper sysAccountMapper;

    private final RedisCache redisCache;

    private final RabbitMQService rabbitMqService;

    /**
     * 查询短信发送记录
     *
     * @param id 短信发送记录主键
     * @return 短信发送记录
     */
    @Override
    public SysSmsRecord selectSysSmsRecordById(String id) {
        return sysSmsRecordMapper.selectSysSmsRecordById(id);
    }

    /**
     * 查询短信发送记录列表
     *
     * @param sysSmsRecord 短信发送记录
     * @return 短信发送记录
     */
    @Override
    public List<SysSmsRecord> selectSysSmsRecordList(SysSmsRecord sysSmsRecord) {
        return sysSmsRecordMapper.selectSysSmsRecordList(sysSmsRecord);
    }

    /**
     * 新增短信发送记录
     *
     * @param sysSmsRecord 短信发送记录
     * @return 结果
     */
    @Override
    public int insertSysSmsRecord(SysSmsRecord sysSmsRecord) {
        sysSmsRecord.setCreateTime(DateUtils.getNowDate());
        return sysSmsRecordMapper.insertSysSmsRecord(sysSmsRecord);
    }

    /**
     * 修改短信发送记录
     *
     * @param sysSmsRecord 短信发送记录
     * @return 结果
     */
    @Override
    public int updateSysSmsRecord(SysSmsRecord sysSmsRecord) {
        sysSmsRecord.setUpdateTime(DateUtils.getNowDate());
        return sysSmsRecordMapper.updateSysSmsRecord(sysSmsRecord);
    }

    /**
     * 批量删除短信发送记录
     *
     * @param ids 需要删除的短信发送记录主键
     * @return 结果
     */
    @Override
    public int deleteSysSmsRecordByIds(String[] ids) {
        return sysSmsRecordMapper.deleteSysSmsRecordByIds(ids);
    }

    /**
     * 删除短信发送记录信息
     *
     * @param id 短信发送记录主键
     * @return 结果
     */
    @Override
    public int deleteSysSmsRecordById(String id) {
        return sysSmsRecordMapper.deleteSysSmsRecordById(id);
    }

    /**
     * 新建待发送短信
     *
     * @param mobile
     * @param content
     * @param sysAccount
     * @return
     */
    public int addSms(String mobile, String content, String sysAccount) {
        SysSmsRecord sysSmsRecord = new SysSmsRecord();
        sysSmsRecord.setId(IdUtil.randomUUID());
        sysSmsRecord.setSysAccount(sysAccount);
        sysSmsRecord.setMobile(mobile);
        sysSmsRecord.setMessage(content);
        sysSmsRecord.setCreateTime(DateUtils.getNowDate());
        sysSmsRecord.setWordCnt((long) content.trim().length());
        sysSmsRecord.setStatus(0);
        sysSmsRecord.setBusiType(1);
        //插入到redis消息队列
        Message<SysSmsRecord> message = new Message<>();
        message.setId(IdUtil.simpleUUID());
        message.setContent(sysSmsRecord);
        sysSmsRecordMapper.insertSysSmsRecord(sysSmsRecord);
        redisCache.add(QueueConstants.SEND_SMS_QUEUE_KEY, message);
        return 1;
    }

    /**
     * 发送短信
     *
     * @param sysSmsRecord
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void sendSms(SysSmsRecord sysSmsRecord) {
        SysSmsRecord upRecord = new SysSmsRecord();
        upRecord.setId(sysSmsRecord.getId());
        upRecord.setUpdateTime(DateUtils.getNowDate());
        String reason = "";
        if (StringUtils.isEmpty(sysSmsRecord.getMessage())) {
            reason = "短信内容不能为空";
        }
        if (!Validator.isMobile(sysSmsRecord.getMobile())) {
            reason = "手机号码格式不正确";
        }
        SysAccount sysAccount = sysAccountMapper.selectOne(new LambdaQueryWrapper<SysAccount>()
                .eq(SysAccount::getSysAccount, sysSmsRecord.getSysAccount()));
        if (null == sysAccount) {
            reason = "账套号[" + sysSmsRecord.getSysAccount() + "不存在]";
        }
        Long cnt = sysSmsRecord.getWordCnt() / MSG_NUB;
        if (sysSmsRecord.getWordCnt() % MSG_NUB != 0)
            cnt++;
        assert sysAccount != null;
        if (cnt.compareTo(Optional.ofNullable(sysAccount.getSmsCnt()).orElse(0L)) > 0) {
            reason = "账套短信余额不足";
        }
        if (StringUtils.isNotEmpty(reason)) {
            upRecord.setStatus(2);
            upRecord.setReason(reason);
        } else {
            SendSmsInfoDto sendSmsInfo = new SendSmsInfoDto();
            sendSmsInfo.setSendUrl(DictUtils.getDictValue("ydsms_params", "url"));
            sendSmsInfo.setAccount(DictUtils.getDictValue("ydsms_params", "account"));
            sendSmsInfo.setUserId(DictUtils.getDictValue("ydsms_params", "user_id"));
            sendSmsInfo.setPassword(DictUtils.getDictValue("ydsms_params", "password"));
            sendSmsInfo.setMobile(sysSmsRecord.getMobile());
            sendSmsInfo.setContent(sysSmsRecord.getMessage());
            sendSmsInfo.setAction("send");
            String signName = DictUtils.getSysConfigValue(sysSmsRecord.getSysAccount(), "sms_sign_name");
            Map<String, Object> retMap = YDMsgUtils.sendMsg(signName, sendSmsInfo);
            if (StringUtils.isNotEmpty(retMap)) {
                if ("Success".equals(MapUtils.getString(retMap, "status"))) {
                    upRecord.setStatus(1);
                    upRecord.setReason(MapUtils.getString(retMap, "msgId"));
                    SysAccount account = new SysAccount();
                    account.setId(sysAccount.getId());
                    account.setUpdateTime(DateUtils.getNowDate());
                    account.setSmsCnt(sysAccount.getSmsCnt() - cnt);
                    sysAccountMapper.updateSysAccount(account);
                } else {
                    upRecord.setStatus(3);
                    upRecord.setReason(MapUtils.getString(retMap, "message"));
                }
            }
        }
        sysSmsRecordMapper.updateSysSmsRecord(upRecord);
    }
}
